package com.naiterui.ehp.bs.esign.api;

import com.naiterui.ehp.bp.bo.esign.EsignServiceConfigBO;
import com.naiterui.ehp.bp.bo.esign.WillTypeBO;
import com.naiterui.ehp.bp.constants.EsignServiceProviderEnum;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bs.esign.api.vo.SignAccountVO;
import com.naiterui.ehp.bs.esign.api.vo.SignFileParamVO;
import com.naiterui.ehp.bs.esign.api.vo.SignUserInfoVO;
import com.naiterui.ehp.bs.esign.api.vo.UserInfoParamVO;
import com.naiterui.ehp.bs.esign.service.IEsignService;
import com.naiterui.ehp.bs.esign.utils.EsignWillTypeEnum;
import com.naiterui.ehp.bs.esign.vo.esign.PreSignResultVO;
import lombok.Builder;
import lombok.Data;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description 签名接口
 * @Author gongbaoqiang
 * @Date 2019/12/20 5:30 PM
 */
public interface ISignService {

    /**
     * 获取当前签名服务提供商配置信息(实现类无需实现该方法)
     *
     * @return
     */
    default EsignServiceConfigBO getServiceConfig() {
        // 获取当前服务商
        EsignServiceProviderEnum providerEnum = this.getCurrentServiceProvider();

        // 获取当前服务商配置
        List<EsignWillTypeEnum> willTypeEnums = EsignWillTypeEnum.getByService(providerEnum.getServiceId());
        List<WillTypeBO> willTypes = willTypeEnums.stream().map(e -> WillTypeBO.builder()
            .name(e.getName())
            .value(e.getValue())
            .checked(false)
            .build()).collect(Collectors.toList());

        return EsignServiceConfigBO.builder().serviceId(providerEnum.getServiceId()).willTypes(willTypes).build();
    }

    /**
     * 获取当前服务提供商
     *
     * @return
     */
    EsignServiceProviderEnum getCurrentServiceProvider();

    /**
     * 获取签章配置(实现类按需重写该方法)
     *
     * @return
     */
    default SealPosConfig getSealPosConfig() {

        return new SealPosConfig() {

            @Override
            public SealPosVO getPrPosDr() {
                return SealPosVO.builder().type(SealPosVO.TYPE_GRID).x(80f).y(40f).keyword("医师").build();
            }

            @Override
            public SealPosVO getPrPosPh() {
                return SealPosVO.builder().type(SealPosVO.TYPE_GRID).x(90f).y(40f).keyword("审核药师").build();
            }

            @Override
            public SealPosVO getPrPosAlPh() {
                return SealPosVO.builder().type(SealPosVO.TYPE_GRID).x(400f).y(25f).keyword("调配/发药").build();
            }

            @Override
            public SealPosVO getEmrPos() {
                return SealPosVO.builder().type(SealPosVO.TYPE_GRID).x(190f).y(60f).keyword("医生").build();
            }

            @Override
            public SealPosVO getNsPosDr() {
                return SealPosVO.builder().type(SealPosVO.TYPE_GRID).x(155f).y(-50f).keyword("请您务必认真阅读并充分理解后再行慎重选择")
                        .build();
            }

            @Override
            public SealPosVO getNsPosPh() {
                return SealPosVO.builder().type(SealPosVO.TYPE_GRID).x(155f).y(-50f).keyword("请您务必认真阅读并充分理解后再行慎重选择")
                        .build();
            }

            @Override
            public SealPosVO getGcPosSource() {
                return SealPosVO.builder().type(SealPosVO.TYPE_GRID).x(80f).y(50f).keyword("医师签字").build();
            }

            @Override
            public SealPosVO getGcPosTarget() {
                return SealPosVO.builder().type(SealPosVO.TYPE_GRID).x(80f).y(50f).keyword("专家签字").build();
            }

        };
    }

    /**
     * 注册账号(自动刷新access_token)
     *
     * @return
     * @throws BusinessException
     */
    SignUserInfoVO registAccount(UserInfoParamVO userInfoParamVO) throws BusinessException;

    /**
     * 更新账号
     * @return
     * @throws BusinessException
     */
    SignUserInfoVO updateAccount(UserInfoParamVO userInfoParamVO) throws BusinessException;

    /**
     * 删除账号
     * @param accountId
     * @throws BusinessException
     */
    void deleteAccount(String accountId) throws BusinessException;


    /**
     * <pre>
     *     发起运营商3要素核身
     *     获取实名认证验证码
     * </pre>
     * @param name 姓名
     * @param phone 手机号
     * @param idCard 身份证号
     * @return
     * @throws BusinessException
     */
    String getRealnameCode(String name , String phone, String idCard) throws BusinessException;

    /**
     * <pre>
     *     校验三要素短信验证码
     *     回写实名认证状态
     * </pre>
     * @param phone
     * @param code
     * @throws BusinessException
     */
    boolean checkRealnameCode(String phone, String code) throws BusinessException;

    /**
     * 生成签章
     * @return
     * @throws BusinessException
     */
    String createSeal(String accountId, String name, String typeface) throws BusinessException;

    /**
     * 获取意向签署验证码
     * @param signParamVO
     * @return
     * @throws BusinessException
     */
    PreSignResultVO preSign(SignFileParamVO signParamVO, SignAccountVO signAccountVO) throws BusinessException;


    /**
     * 签名接口，并进行验签
     *
     * @return
     * @throws BusinessException
     */
    void sign(SignFileParamVO signParamVO, SignAccountVO signAccountVO, IEsignService callback) throws BusinessException;

    /**
     * 修改静态签名密码
     *
     * @param openId
     * @param newPassword
     */
    void resetSignPwd(String openId, String newPassword) throws BusinessException;



    /**
     * 签章定位配置
     */
    interface SealPosConfig {

        /**
         * 获取处方签章配置-医生
         *
         * @return
         */
        SealPosVO getPrPosDr();

        /**
         * 获取处方签章配置-药师
         *
         * @return
         */
        SealPosVO getPrPosPh();

        /**
         * 获取处方签章配置-调配药师
         * @return
         */
        SealPosVO getPrPosAlPh();

        /**
         * 获取病例签章配置
         *
         * @return
         */
        SealPosVO getEmrPos();

        /**
         * 获取医师免签签章配置
         *
         * @return
         */
        SealPosVO getNsPosDr();

        /**
         * 获取药师免签签章配置
         *
         * @return
         */
        SealPosVO getNsPosPh();

        /**
         * 获取会诊发起医师签章配置
         *
         * @return
         */
        SealPosVO getGcPosSource();

        /**
         * 获取会诊受邀专家签章配置
         *
         * @return
         */
        SealPosVO getGcPosTarget();
    }

    @Builder
    @Data
    class SealPosVO {

        public static final Integer TYPE_GRID = 1;
        public static final Integer TYPE_KEY = 2;

        /**
         * 定位方式(1:坐标, 2:关键字)
         */
        private Integer type;

        /**
         * 定位坐标 x
         */
        private Float x;

        /**
         * 定位坐标 y
         */
        private Float y;

        /**
         * 定位关键字(仅坐标定位时有效)
         */
        private String keyword;
    }

}
